//============================================================================
// Name        : player_settings.cpp
// Author      : dfoelber
//============================================================================

// INCLUDES //
#include "settings/player_settings.h"
#include "util.h"
#include <iostream>
#include <stdlib.h>
//////////////

using namespace std;

/**
* Constructor
**/
PlayerSettings::PlayerSettings()
{
	playerName = DEFAULT_PLAYER_NAME;
}

/**
* Deconstructor
**/
PlayerSettings::~PlayerSettings()
{
}

/**
* Loads player settings from a file.
* 
* @param filename The filename of the file
* @return If the file was opened
**/
bool PlayerSettings::Load(string filename)
{
	bool deckLoading = false;
	string line;
	ifstream file(filename.c_str());
	if( file.is_open() )
	{
		while( !file.eof() )
		{
			getline( file, line );
			if( line.length() > 0 && line[0] != '#' )
			{
				vector<string> v = Util::Split(Util::RemoveWhiteSpaces(line), '=');
				if( v.size() > 0 )
				{
					if( v[0] == KEY_DECK_END )
					{
						deckLoading = false;
					}
					else if( deckLoading )
					{
						deckData.push_back(line);
					}
					else if( v[0] == KEY_PLAYER_NAME )
					{
						playerName = v[1];
					}
					else if( v[0] == KEY_DECK_START )
					{
						deckData.clear();
						deckLoading = true;
					}
				}
			}
		}
		
		file.close();
		return true;
	}
	
	return false;
}

/**
* Gets the player name.
**/
string PlayerSettings::GetPlayerName()
{
	return playerName;
}

/**
* Creates the player's deck.
**/
vector<CardInfo*> PlayerSettings::CreateDeck()
{
	vector<CardInfo*> deck;
	
	while( deckData.size() >= 8 )
	{
		int eraseLineCount = 8;
		vector<vector<char> > cardCost;
		for( int i = 2; i < 8; i++ )
		{
			if( deckData[i].length() == 6 )
			{
				vector<char> v;
				v.push_back(deckData[i][0] == '-' ? ' ' : deckData[i][0]);
				v.push_back(deckData[i][1] == '-' ? ' ' : deckData[i][1]);
				v.push_back(deckData[i][2] == '-' ? ' ' : deckData[i][2]);
				v.push_back(deckData[i][3] == '-' ? ' ' : deckData[i][3]);
				v.push_back(deckData[i][4] == '-' ? ' ' : deckData[i][4]);
				v.push_back(deckData[i][5] == '-' ? ' ' : deckData[i][5]);
				cardCost.push_back(v);
			}
		}
		
		if( cardCost.size() == 6 )
		{
			vector<Effect*> effects;
			
			bool cont = true;
			while( cont && (int)deckData.size() > eraseLineCount )
			{
				if( deckData[eraseLineCount] == EFFECT_DIRECT_DAMAGE && (int)deckData.size() >= eraseLineCount + EFFECT_LINE_COUNT )
				{
					vector<int> damage;
					vector<string> temp = Util::Split(deckData[eraseLineCount + 9],',');
					for( int i = 0; i < (int)temp.size(); i++ )
						damage.push_back(atoi(temp[i].c_str()));
					
					DirectDamageEffect* effect = new DirectDamageEffect(damage,
							deckData[eraseLineCount + 1],
							deckData[eraseLineCount + 2],
							atof(deckData[eraseLineCount + 3].c_str()), 
							deckData[eraseLineCount + 4], 
							deckData[eraseLineCount + 5],
							deckData[eraseLineCount + 6],
							deckData[eraseLineCount + 7],
							deckData[eraseLineCount + 8]);
					
					effects.push_back(effect);
					
					eraseLineCount += EFFECT_LINE_COUNT;
					
					cont = true;
				}
				else if( deckData[eraseLineCount] == EFFECT_ALIGNMENT_CHANGE && (int)deckData.size() >= eraseLineCount + EFFECT_LINE_COUNT )
				{
					vector<string> change;
					vector<string> temp = Util::Split(deckData[eraseLineCount + 9],',');
					for( int i = 0; i < (int)temp.size(); i++ )
						change.push_back(temp[i]);
					
					AlignmentChangeEffect* effect = new AlignmentChangeEffect(change,
							deckData[eraseLineCount + 1],
							deckData[eraseLineCount + 2],
							atof(deckData[eraseLineCount + 3].c_str()), 
							deckData[eraseLineCount + 4], 
							deckData[eraseLineCount + 5],
							deckData[eraseLineCount + 6],
							deckData[eraseLineCount + 7],
							deckData[eraseLineCount + 8]);
					
					effects.push_back(effect);
					
					eraseLineCount += EFFECT_LINE_COUNT;
					
					cont = true;
				}
				else if( deckData[eraseLineCount] == EFFECT_DAMAGE_OVER_TIME && (int)deckData.size() >= eraseLineCount + EFFECT_LINE_COUNT )
				{
					vector<DoTEffect::DoT> damage;
					vector<string> temp = Util::Split(deckData[eraseLineCount + 9],',');
					for( int i = 0; i < (int)temp.size(); i++ )
					{
						vector<string> ddata = Util::Split(temp[i],'|');
						if( (int)ddata.size() == 3 )
						{
							DoTEffect::DoT dot;
							dot.damage = atoi(ddata[0].c_str());
							dot.occur = atoi(ddata[1].c_str());
							dot.time = atoi(ddata[2].c_str());
							damage.push_back(dot);
						}
					}
					
					DoTEffect* effect = new DoTEffect(damage,
							deckData[eraseLineCount + 1],
							deckData[eraseLineCount + 2],
							atof(deckData[eraseLineCount + 3].c_str()), 
							deckData[eraseLineCount + 4], 
							deckData[eraseLineCount + 5],
							deckData[eraseLineCount + 6],
							deckData[eraseLineCount + 7],
							deckData[eraseLineCount + 8]);
					
					effects.push_back(effect);
					
					eraseLineCount += EFFECT_LINE_COUNT;
					
					cont = true;
				}
				else
				{
					cont = false;
				}
			}
			
			CardInfo* info = new CardInfo(deckData[0], cardCost, effects, deckData[1]);
			deck.push_back(info);
		}
		
		deckData.erase(deckData.begin(),deckData.begin()+eraseLineCount);
	}
	
	return deck;
}
